package star.cloud.asme.system.role.menu;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import star.cloud.asme.base.dto.Result;
import star.cloud.asme.base.mybatis.IBaseServiceImpl;
import star.cloud.asme.system.permission.PermissionService;

import java.util.List;
import java.util.Objects;

@Service
@RequiredArgsConstructor
@Slf4j
public class MenuServiceImpl extends IBaseServiceImpl<MenuMapper, Menu> implements MenuService {
    private final MenuMapper menuMapper;
    private final PermissionService permissionService;

    @Override
    public Result<List<Menu>> getListByConditions(Menu entity) {
        LambdaQueryWrapper<Menu> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Menu::getRoleId, entity.getRoleId());
        List<Menu> menus = menuMapper.selectList(lambdaQueryWrapper);
        return Result.ok(menus);
    }

    @Override
    public Result<?> resetMenusByRoleId(MenuDTO menuDTO) {
        Long roleId = menuDTO.getRoleId();
        List<String> newMenus = menuDTO.getMenus();
        //获取更新之前角色拥有的菜单列表
        List<String> oldMenus = menuMapper.selectListByRoleId(roleId).stream().map(Menu::getTitle).toList();
        if (newMenus != null && !newMenus.isEmpty()) {
            if (newMenus.size() > oldMenus.size()) {
                //将新的menuTitle添加到数据库中去
                List<String> additionalMenus = newMenus.stream().filter(item -> !(oldMenus.contains(item))).toList();
                batchSaveMenus(menuDTO, roleId, additionalMenus);
            } else if (newMenus.size() < oldMenus.size()) {
                //将减少的的menuTitle从数据库中去除
                List<String> deletedMenus = oldMenus.stream().filter(item -> !(newMenus.contains(item))).toList();
                deletedMenus.forEach(deletedMenu -> menuMapper.deleteByRoleIdAndMenuTitle(roleId, deletedMenu));
                //将从role中删除的菜单关联的权限删除
                permissionService.deleteByRoleNameAndMenuTitles(menuDTO.getRoleName(), deletedMenus);
            } else {
                log.info("菜单内容没有发生变化");
            }
        } else {
            //删除所有roleId的数据
            menuMapper.deleteByRoleId(roleId);
            permissionService.myDeleteByRoleName(menuDTO.getRoleName());
        }
        return Result.ok();
    }

    @Override
    public Result<List<String>> getMenuTitleListByUserId(Long userId) {
        List<String> menuTitleList = menuMapper.selectMenuTitleListByUserId(userId);
        return Result.ok(menuTitleList.stream().filter(Objects::nonNull).distinct().toList());
    }

    private void batchSaveMenus(MenuDTO menuDTO, Long roleId, List<String> menus) {
        menus.forEach(title -> {
            Menu menu = Menu.builder().build();
            menu.setRoleId(roleId);
            menu.setTitle(title);
            menu.setCreatorId(menuDTO.getCreatorId());
            menu.setUpdaterId(menuDTO.getUpdaterId());
            menuMapper.insert(menu);
        });
    }
}